package org.dromara.system.kernel;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.constants.OrderConstants;
import org.dromara.system.domain.*;
import org.dromara.system.mapper.*;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 禁用商户信息
 *
 * @author gavino
 * @date 2025/01/05 15:23
 */
@Service
@RequiredArgsConstructor
public class DisableClientKernel {

    private final SysUserMapper userMapper;
    private final PayAppMapper payAppMapper;
    private final PayOrderMapper payOrderMapper;
    private final PayOrderLogMapper payOrderLogMapper;
    private final PayAccountMapper payAccountMapper;
    private final PayGroupMapper payGroupMapper;
    private final PayGroupTypeMapper payGroupTypeMapper;
    private final PayGroupAccountMapper payGroupAccountMapper;
    private final PayBlackMapper payBlackMapper;
    private final PayPolicyMapper policyMapper;
    private final PayLinkMapper payLinkMapper;
    private final EmailAccountMapper emailAccountMapper;
    private final EmailTemplateMapper emailTemplateMapper;
    private final EmailQueueMapper emailQueueMapper;
    private final EmailListMapper emailListMapper;
    private final RestHighLevelClient restHighLevelClient;
    @Value("${spring.elasticsearch.environment}")
    private String environment;

    /**
     * 禁用代理下的商户、应用
     *
     * @param agentId 商户ID
     */
    @Transactional
    public void disableClient(Long agentId) {
        // 停用子商户
        userMapper.update(new LambdaUpdateWrapper<SysUser>().eq(SysUser::getAgentId, agentId).set(SysUser::getStatus, 1));
        // 下线应用
        payAppMapper.update(new LambdaUpdateWrapper<PayApp>().eq(PayApp::getAgentId, agentId).set(PayApp::getStatus, 0));
    }

    /**
     * 删除代理以及商户所有信息
     *
     * @param agentId 商户ID
     */
    @Transactional
    public void deleteClient(Long agentId) {

        // 删除子商户
        userMapper.delete(new LambdaQueryWrapper<SysUser>().eq(SysUser::getAgentId, agentId));

        // 删除应用
        payAppMapper.delete(new LambdaQueryWrapper<PayApp>().eq(PayApp::getAgentId, agentId));

        // 删除订单
        payOrderMapper.delete(new LambdaQueryWrapper<PayOrder>().eq(PayOrder::getAgentId, agentId));

        // 删除订单日志
        List<Long> orderIds = payOrderMapper.selectList(new LambdaQueryWrapper<PayOrder>().eq(PayOrder::getAgentId, agentId).select(PayOrder::getOrderId)).stream().map(PayOrder::getOrderId).toList();
        Lists.partition(orderIds, 3000).forEach(ids -> payOrderLogMapper.delete(new LambdaQueryWrapper<PayOrderLog>().in(PayOrderLog::getOrderId, ids)));

        // 删除es订单
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder()
            .filter(new TermQueryBuilder("agentId", agentId));
        DeleteByQueryRequest request = new DeleteByQueryRequest("pay_order_" + environment);
        request.setQuery(queryBuilder);
        try {
            restHighLevelClient.deleteByQuery(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("删除es订单失败，agentId = " + agentId);
        }

        // 删除收款账号
        LambdaQueryWrapper<PayAccount> query = new LambdaQueryWrapper<PayAccount>().eq(PayAccount::getAgentId, LoginHelper.getUserId()).select(PayAccount::getAccountId);
        List<PayAccount> list = payAccountMapper.selectList(query);
        for (PayAccount account : list) {
            RedisUtils.deleteObject(OrderConstants.pay_account_cache + account.getAccountId());
        }
        payAccountMapper.delete(query);

        // 删除轮询组
        LambdaQueryWrapper<PayGroup> groupQuery = new LambdaQueryWrapper<PayGroup>().eq(PayGroup::getAgentId, agentId).select(PayGroup::getGroupId);
        List<PayGroup> groups = payGroupMapper.selectList(groupQuery);
        payGroupMapper.delete(groupQuery);

        // 删除轮询组收款平台
        if (!groups.isEmpty()) {
            payGroupTypeMapper.delete(new LambdaQueryWrapper<PayGroupType>().in(PayGroupType::getGroupId, groups.stream().map(PayGroup::getGroupId).collect(Collectors.toSet())));
        }

        // 删除轮询组账号
        List<PayGroupAccount> groupAccounts = payGroupAccountMapper.selectList(new LambdaQueryWrapper<PayGroupAccount>().eq(PayGroupAccount::getAgentId, agentId).select(PayGroupAccount::getId));
        for (PayGroupAccount groupAccount : groupAccounts) {
            RedisUtils.deleteObject(OrderConstants.pay_group_account + groupAccount.getId());
        }
        payGroupAccountMapper.delete(new LambdaQueryWrapper<PayGroupAccount>().eq(PayGroupAccount::getAgentId, agentId));

        // 删除黑名单
        payBlackMapper.delete(new LambdaQueryWrapper<PayBlack>().eq(PayBlack::getCreateId, agentId));

        // 删除风控策略
        List<PayPolicy> policies = policyMapper.selectList(new LambdaQueryWrapper<PayPolicy>().eq(PayPolicy::getAgentId, agentId).select(PayPolicy::getPolicyId));
        for (PayPolicy policy : policies) {
            RedisUtils.deleteObject(OrderConstants.policy_config + policy.getPolicyId());
        }
        policyMapper.delete(new LambdaQueryWrapper<PayPolicy>().eq(PayPolicy::getAgentId, agentId));

        // 删除支付链接
        payLinkMapper.delete(new LambdaQueryWrapper<PayLink>().eq(PayLink::getAgentId, agentId));

        // 删除邮件账号
        emailAccountMapper.delete(new LambdaQueryWrapper<EmailAccount>().eq(EmailAccount::getCreateId, agentId));

        // 删除邮件模板
        emailTemplateMapper.delete(new LambdaQueryWrapper<EmailTemplate>().eq(EmailTemplate::getCreateId, agentId));

        // 删除邮件队列
        emailQueueMapper.delete(new LambdaQueryWrapper<EmailQueue>().eq(EmailQueue::getCreateId, agentId));

        // 删除邮件
        emailListMapper.delete(new LambdaQueryWrapper<EmailList>().eq(EmailList::getCreateId, agentId));

    }
}
